home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / UNIX / C / INDENT / ARGS.C next >
C/C++ Source or Header  |  1989-09-03  |  13KB  |  411 lines

  1. /*
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by the University of California, Berkeley, the University of Illinois,
  13.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  14.  * or Sun Microsystems may not be used to endorse or promote products
  15.  * derived from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)args.c    5.8 (Berkeley) 5/15/89";
  23. #endif /* not lint */
  24.  
  25. /*
  26.  * Argument scanning and profile reading code.  Default parameters are set
  27.  * here as well.
  28.  */
  29.  
  30. #include "indent_globs.h"
  31. #include <ctype.h>
  32. #include "version.h"
  33.  
  34. int else_endif_col;
  35.  
  36. extern char *in_name;
  37.  
  38. char       *getenv(), *index();
  39.  
  40. /* profile types */
  41. enum profile {PRO_BOOL, /* boolean */
  42.         PRO_INT, /* integer */
  43.         PRO_FONT, /* troff font */
  44.         PRO_IGN, /* ignore it */
  45.         PRO_KEY, /* -T switch */
  46.         PRO_SETTINGS, /* bundled set of settings */
  47.         PRO_PRSTRING, /* Print string and exit */
  48.           };
  49.  
  50. /* profile specials for booleans */
  51. enum on_or_off {
  52.   ONOFF_NA, /* Not applicable.  Used in table for non-booleans.  */
  53.   OFF, /* This option turns on the boolean variable in question.  */
  54.   ON  /* it turns it off */
  55. };
  56.  
  57. /* Explicit flags for each option.  */
  58. static int exp_T = 0;
  59. static int exp_bacc = 0;
  60. static int exp_badp = 0;
  61. static int exp_bad = 0;
  62. static int exp_bap = 0;
  63. static int exp_bbb = 0;
  64. static int exp_bc = 0;
  65. static int exp_bli = 0;
  66. static int exp_bl = 0;
  67. static int exp_bs = 0;
  68. static int exp_cdb = 0;
  69. static int exp_cd = 0;
  70. static int exp_ce = 0;
  71. static int exp_ci = 0;
  72. static int exp_cli = 0;
  73. static int exp_cp = 0;
  74. static int exp_cs = 0;
  75. static int exp_c = 0;
  76. static int exp_di = 0;
  77. static int exp_dj = 0;
  78. static int exp_d = 0;
  79. static int exp_eei = 0;
  80. static int exp_ei = 0;
  81. static int exp_fbc = 0;
  82. static int exp_fbx = 0;
  83. static int exp_fb = 0;
  84. static int exp_fc1 = 0;
  85. static int exp_fca = 0;
  86. static int exp_fc = 0;
  87. static int exp_fk = 0;
  88. static int exp_fs = 0;
  89. static int exp_gnu = 0;
  90. static int exp_ip = 0;
  91. static int exp_i = 0;
  92. static int exp_lc = 0;
  93. static int exp_lp = 0;
  94. static int exp_l = 0;
  95. static int exp_pcs = 0;
  96. static int exp_psl = 0;
  97. static int exp_pro = 0;
  98. static int exp_ps = 0;
  99. static int exp_kr = 0;
  100. static int exp_sc = 0;
  101. static int exp_sob = 0;
  102. static int exp_ss = 0;
  103. static int exp_st = 0;
  104. static int exp_troff = 0;
  105. static int exp_v = 0;
  106. static int exp_version = 0;
  107.  
  108. /* The following variables are controlled by command line parameters and
  109.    their meaning is explained in indent_globs.h.  */
  110. int leave_comma;
  111. int decl_com_ind;
  112. int case_indent;
  113. int com_ind;
  114. int decl_indent;
  115. int ljust_decl;
  116. int unindent_displace;
  117. int else_if;
  118. int indent_parameters;
  119. int ind_size;
  120. int blanklines_after_procs;
  121. int use_stdinout;
  122.  
  123. /* Name of where options are currently being read from (one of the
  124.    .indent.pro files, or the command line).  */
  125. char *option_source = "?";
  126.  
  127. /*
  128.  * N.B.: because of the way the table here is scanned, options whose names are
  129.  * substrings of other options must occur later; that is, with -lp vs -l, -lp
  130.  * must be first.  Also, while (most) booleans occur more than once, the last
  131.  * default value is the one actually assigned.
  132.  */
  133. struct pro {
  134.     char       *p_name;        /* name, eg -bl, -cli */
  135.     enum profile p_type;
  136.     int         p_default;    /* the default value (if int) */
  137.  
  138.     /* If p_type == PRO_BOOL, ON or OFF to tell how this switch affects
  139.          the variable.
  140.        Not used for other p_type's.  */
  141.     enum on_or_off p_special;
  142.  
  143.     /* if p_type == PRO_SETTINGS, a (char *) pointing to a list of the
  144.        switches to set, separated by NULs, terminated by 2 NULs.
  145.        if p_type == PRO_BOOL, PRO_INT, or PRO_FONT, address of the
  146.        variable that gets set by the option.
  147.        if p_type == PRO_PRSTRING, a (char *) pointing to the string.  */
  148.     int *p_obj;
  149.  
  150.     /* Points to a nonzero value (allocated statically for all options)
  151.        if the option has been specified explicitly.  This is necessary
  152.        because for boolean options, the options to set and reset the
  153.        variable must share the explicit flag.  */
  154.     int* p_explicit;
  155. };
  156.  
  157. struct pro pro[] = {
  158.  
  159.     {"T", PRO_KEY, 0, ONOFF_NA, 0, &exp_T},
  160.     {"bacc", PRO_BOOL, false, ON,
  161.       &blanklines_around_conditional_compilation, &exp_bacc},
  162.     {"badp", PRO_BOOL, false, ON,
  163.        &blanklines_after_declarations_at_proctop, &exp_badp},
  164.     {"bad", PRO_BOOL, false, ON, &blanklines_after_declarations, &exp_bad},
  165.     {"bap", PRO_BOOL, false, ON, &blanklines_after_procs, &exp_bap},
  166.     {"bbb", PRO_BOOL, false, ON, &blanklines_before_blockcomments, &exp_bbb},
  167.     {"bc", PRO_BOOL, true, OFF, &leave_comma, &exp_bc},
  168.     {"bli", PRO_INT, 0, ONOFF_NA, &brace_indent, &exp_bli},
  169.     {"bl", PRO_BOOL, true, OFF, &btype_2, &exp_bl},
  170.     {"br", PRO_BOOL, true, ON, &btype_2, &exp_bl},
  171.     {"bs", PRO_BOOL, false, ON, &Bill_Shannon, &exp_bs},
  172.     {"cdb", PRO_BOOL, true, ON, &comment_delimiter_on_blankline, &exp_cdb},
  173.     {"cd", PRO_INT, 0, ONOFF_NA, &decl_com_ind, &exp_cd},
  174.     {"ce", PRO_BOOL, true, ON, &cuddle_else, &exp_ce},
  175.     {"ci", PRO_INT, 0, ONOFF_NA, &continuation_indent, &exp_ci},
  176.     {"cli", PRO_INT, 0, ONOFF_NA, &case_indent, &exp_cli},
  177.     {"cp", PRO_INT, 33, ONOFF_NA, &else_endif_col, &exp_cp},
  178.     {"cs", PRO_BOOL, true, ON, &cast_space, &exp_cs},
  179.     {"c", PRO_INT, 33, ONOFF_NA, &com_ind, &exp_c},
  180.     {"di", PRO_INT, 16, ONOFF_NA, &decl_indent, &exp_di},
  181.     {"dj", PRO_BOOL, false, ON, &ljust_decl, &exp_dj},
  182.     {"d", PRO_INT, 0, ONOFF_NA, &unindent_displace, &exp_d},
  183.     {"eei", PRO_BOOL, false, ON, &extra_expression_indent, &exp_eei},
  184.     {"ei", PRO_BOOL, true, ON, &else_if, &exp_ei},
  185.     {"fbc", PRO_FONT, 0, ONOFF_NA, (int *) &blkcomf, &exp_fbc},
  186.     {"fbx", PRO_FONT, 0, ONOFF_NA, (int *) &boxcomf, &exp_fbx},
  187.     {"fb", PRO_FONT, 0, ONOFF_NA, (int *) &bodyf, &exp_fb},
  188.     {"fc1", PRO_BOOL, true, ON, &format_col1_comments, &exp_fc1},
  189.     {"fca", PRO_BOOL, true, ON, &format_comments, &exp_fca},
  190.     {"fc", PRO_FONT, 0, ONOFF_NA, (int *) &scomf, &exp_fc},
  191.     {"fk", PRO_FONT, 0, ONOFF_NA, (int *) &keywordf, &exp_fk},
  192.     {"fs", PRO_FONT, 0, ONOFF_NA, (int *) &stringf, &exp_fs},
  193.     {"gnu", PRO_SETTINGS, 0, ONOFF_NA,
  194.       (int *)"-nbad\0-bap\0-nbbb\0-nbc\0-bl\0-ncdb\0-cs\0-nce\0-di1\0-ndj\0\
  195. -ei\0-nfc1\0-i2\0-ip5\0-lp\0-pcs\0-nps\0-psl\0-nsc\0-nsob\0-bli2\0-ss\0\
  196. -cp1\0-nfca\0", &exp_gnu},
  197.     {"ip", PRO_INT, 4, ON, &indent_parameters, &exp_ip},
  198.     {"i", PRO_INT, 4, ONOFF_NA, &ind_size, &exp_i},
  199.     {"kr", PRO_SETTINGS, 0, ONOFF_NA,
  200.        (int *)"-nbad\0-bap\0-nbbb\0-nbc\0-br\0-c33\0-cd33\0-ncdb\0-ce\0\
  201. -ci4\0-cli0\0-d0\0-di1\0-nfc1\0-i4\0-ip0\0-l75\0-lp\0-npcs\0-npsl\0-cs\0\
  202. -nsc\0-nsc\0-nsob\0-nfca\0-cp33\0-nss\0", &exp_kr},
  203.     {"lc", PRO_INT, 0, ONOFF_NA, &block_comment_max_col, &exp_lc},
  204.     {"lp", PRO_BOOL, true, ON, &lineup_to_parens, &exp_lp},
  205.     {"l", PRO_INT, 78, ONOFF_NA, &max_col, &exp_l},
  206.     {"nbacc", PRO_BOOL, false, OFF,
  207.        &blanklines_around_conditional_compilation, &exp_bacc},
  208.     {"nbadp", PRO_BOOL, false, OFF,
  209.        &blanklines_after_declarations_at_proctop, &exp_badp},
  210.     {"nbad", PRO_BOOL, false, OFF, &blanklines_after_declarations, &exp_bad},
  211.     {"nbap", PRO_BOOL, false, OFF, &blanklines_after_procs, &exp_bap},
  212.     {"nbbb", PRO_BOOL, false, OFF, &blanklines_before_blockcomments, &exp_bbb},
  213.     {"nbc", PRO_BOOL, true, ON, &leave_comma, &exp_bc},
  214.     {"nbs", PRO_BOOL, false, OFF, &Bill_Shannon, &exp_bs},
  215.     {"ncdb", PRO_BOOL, true, OFF, &comment_delimiter_on_blankline, &exp_cdb},
  216.     {"nce", PRO_BOOL, true, OFF, &cuddle_else, &exp_ce},
  217.     {"ncs", PRO_BOOL, true, OFF, &cast_space, &exp_cs},
  218.     {"ndj", PRO_BOOL, false, OFF, &ljust_decl, &exp_dj},
  219.     {"neei", PRO_BOOL, false, OFF, &extra_expression_indent, &exp_eei},
  220.     {"nei", PRO_BOOL, true, OFF, &else_if, &exp_ei},
  221.     {"nfc1", PRO_BOOL, true, OFF, &format_col1_comments, &exp_fc1},
  222.     {"nfca", PRO_BOOL, true, OFF, &format_comments, &exp_fca},
  223.     {"nlp", PRO_BOOL, true, OFF, &lineup_to_parens, &exp_lp},
  224.     {"npcs", PRO_BOOL, false, OFF, &proc_calls_space, &exp_pcs},
  225.     {"npro", PRO_IGN, 0, ONOFF_NA, 0, &exp_pro},
  226.     {"npsl", PRO_BOOL, true, OFF, &procnames_start_line, &exp_psl},
  227.     {"nps", PRO_BOOL, false, OFF, &pointer_as_binop, &exp_ps},
  228.     {"nsc", PRO_BOOL, true, OFF, &star_comment_cont, &exp_sc},
  229.     {"nsob", PRO_BOOL, false, OFF, &swallow_optional_blanklines, &exp_sob},
  230.     {"nss", PRO_BOOL, false, OFF, &space_sp_semicolon, &exp_ss},
  231.     {"nv", PRO_BOOL, false, OFF, &verbose, &exp_v},
  232.     {"pcs", PRO_BOOL, false, ON, &proc_calls_space, &exp_pcs},
  233.     {"psl", PRO_BOOL, true, ON, &procnames_start_line, &exp_psl},
  234.     {"ps", PRO_BOOL, false, ON, &pointer_as_binop, &exp_ps},
  235.     {"sc", PRO_BOOL, true, ON, &star_comment_cont, &exp_sc},
  236.     {"sob", PRO_BOOL, false, ON, &swallow_optional_blanklines, &exp_sob},
  237.     {"ss", PRO_BOOL, false, ON, &space_sp_semicolon, &exp_ss},
  238.     {"st", PRO_BOOL, false, ON, &use_stdinout, &exp_st},
  239.     {"troff", PRO_BOOL, false, ON, &troff, &exp_troff},
  240.     {"version", PRO_PRSTRING, 0, ONOFF_NA,
  241.        (int *)VERSION_STRING, &exp_version},
  242.     {"v", PRO_BOOL, false, ON, &verbose, &exp_v},
  243.  
  244.     /* Signify end of structure.  */
  245.     {0, PRO_IGN, 0, ONOFF_NA, 0, 0}
  246. };
  247.  
  248. /*
  249.  * set_profile reads $HOME/.indent.pro and ./.indent.pro and handles arguments
  250.  * given in these files.
  251.  */
  252. set_profile()
  253. {
  254.     register FILE *f;
  255.     char *fname;
  256.     static char prof[] = ".indent.pro";
  257.     char *homedir;
  258.  
  259.     homedir = getenv("HOME");
  260.     fname = xmalloc(strlen(homedir) + 10 + sizeof prof);
  261.     sprintf(fname, "%s/%s", homedir, prof);
  262.     if ((f = fopen(option_source = fname, "r")) != NULL) {
  263.     scan_profile(f);
  264.     (void) fclose(f);
  265.     }
  266.     if ((f = fopen(option_source = prof, "r")) != NULL) {
  267.     scan_profile(f);
  268.     (void) fclose(f);
  269.     }
  270.     option_source = "Command line";
  271.     free (fname);
  272. }
  273.  
  274. scan_profile(f)
  275.     register FILE *f;
  276. {
  277.     register int i;
  278.     register char *p;
  279.     char        buf[BUFSIZ];
  280.  
  281.     while (1) {
  282.     for (p = buf; (i = getc(f)) != EOF && (*p = i) > ' '; ++p);
  283.     if (p != buf) {
  284.         *p++ = 0;
  285.         if (verbose)
  286.         printf("profile: %s\n", buf);
  287.         set_option(buf, 1);
  288.     }
  289.     else if (i == EOF)
  290.         return;
  291.     }
  292. }
  293.  
  294. /* S1 should be a string.  S2 should be a string, perhaps followed by
  295.    an argument.  Compare the two, returning true if they are equal,
  296.    and if they are equal set *START_PARAM to point to the argument
  297.    in S2.  */
  298. eqin(s1, s2, start_param)
  299.      register char *s1;
  300.      register char *s2;
  301.      char **start_param;
  302. {
  303.     while (*s1) {
  304.     if (*s1++ != *s2++)
  305.         return (false);
  306.     }
  307.     *start_param = s2;
  308.     return (true);
  309. }
  310.  
  311. /*
  312.  * Set the defaults.
  313.  */
  314. set_defaults()
  315. {
  316.     register struct pro *p;
  317.  
  318.     for (p = pro; p->p_name; p++)
  319.     if (p->p_type == PRO_BOOL || p->p_type == PRO_INT)
  320.         *p->p_obj = p->p_default;
  321. }
  322.  
  323. /* Process an option ARG (e.g. "-l60").  
  324.    EXPLICIT should be nonzero iff the argument is being explicitly
  325.    specified (as opposed to being taken from a PRO_SETTINGS group of
  326.    settings).  */
  327.  
  328. set_option (arg, explicit)
  329.      char *arg;
  330.      int explicit;
  331. {
  332.     struct pro *p;
  333.     char       *param_start;
  334.  
  335.     arg++;            /* ignore leading "-" */
  336.     for (p = pro; p->p_name; p++)
  337.     if (*p->p_name == *arg && eqin(p->p_name, arg, ¶m_start))
  338.         goto found;
  339.     fprintf(stderr, "indent: %s: unknown parameter \"%s\"\n", option_source, arg - 1);
  340.     exit(1);
  341. found:
  342.     /* If the parameter has been explicitly specified, we don't */
  343.     /* want a group of bundled settings to override the explicit */
  344.     /* setting.  */
  345.     if (explicit || !*(p->p_explicit))
  346.       {
  347.     if (explicit)
  348.       *(p->p_explicit) = 1;
  349.     
  350.     switch (p->p_type) {
  351.       
  352.         case PRO_PRSTRING:
  353.       puts ((char *)p->p_obj);
  354.       exit (0);
  355.  
  356.     case PRO_SETTINGS:
  357.       {
  358.         char *t;  /* current position */
  359.         
  360.         t = (char *)p->p_obj;
  361.         do
  362.           {
  363.         set_option(t, 0);
  364.         /* advance to character following next NUL */
  365.         while (*t++) ;
  366.           }
  367.         while (*t);
  368.       }
  369.       
  370.     case PRO_IGN:
  371.       break;
  372.       
  373.     case PRO_KEY:
  374.       if (*param_start == 0)
  375.         goto need_param;
  376.       {
  377.         register char *str = (char *) xmalloc(strlen(param_start) + 1);
  378.         strcpy(str, param_start);
  379.         addkey(str, 4);
  380.       }
  381.       break;
  382.       
  383.     case PRO_BOOL:
  384.       if (p->p_special == OFF)
  385.         *p->p_obj = false;
  386.       else
  387.         *p->p_obj = true;
  388.       break;
  389.  
  390.     case PRO_INT:
  391.       if (!isdigit(*param_start)) {
  392.     need_param:
  393.           fprintf(stderr, "indent: %s: ``%s'' requires a parameter\n",
  394.               option_source, arg - 1);
  395.         exit(1);
  396.       }
  397.       *p->p_obj = atoi(param_start);
  398.       break;
  399.       
  400.     case PRO_FONT:
  401.       parsefont((struct fstate *) p->p_obj, param_start);
  402.       break;
  403.       
  404.     default:
  405.       fprintf(stderr, "indent: set_option: internal error: p_type %d\n",
  406.           p->p_type);
  407.       exit(1);
  408.     }
  409.       }
  410. }
  411.